﻿using BussinessLogicLayer;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TestingSystem.Common;

namespace TestingSystem.TestingManager
{
    public partial class AddEditTestSectionForm : Form
    {
        private decimal _section_ID = -1;
        public TestSection Section { get; set; }
        private BindingList<QuestionDisplay> listQuestion = new BindingList<QuestionDisplay>();
        private BindingList<QuestionDisplay> listQuestionSelected = new BindingList<QuestionDisplay>();

        public AddEditTestSectionForm(decimal section_ID, TestSection section)
        {
            InitializeComponent();
            this._section_ID = section_ID;
            if (section != null)
            {
                Section = section;
            }
        }

        private void AddEditTestSectionForm_Load(object sender, EventArgs e)
        {
            try
            {
                // Load and binding list users to user filter combobox
                this.cboLectureFilter.DataSource = this.GetUsers();
                this.cboLectureFilter.SelectedIndex = -1;

                // Load list difficulty
                this.cboDifficult.DataSource = this.GetDifficulty();
                this.cboDifficult.SelectedIndex = -1;

                // Load list question types
                this.cboType.DataSource = this.GetQuestionTypes();
                this.cboType.SelectedIndex = -1;

                this.dgvQuestion.DataSource = this.listQuestion;
                this.dgvQuestionSelected.DataSource = this.listQuestionSelected;

                // Edit 
                if (this._section_ID != -1)
                {
                    var testSection = BLL_Test_Section.GetTestSection(this._section_ID);
                    txtDesc.Text = testSection.TEST_SECTION_DESC.Trim();

                    var list = BLL_Test_Section.GetQuestions(this._section_ID);

                    // Store list question
                    foreach (var item in list)
                    {
                        var q = new QuestionDisplay();

                        q.User_ID = item.USER_ID;
                        q.Question_ID = item.QUESTION_ID;
                        q.Question_Desc = item.QUESTION_DESCRIPTION;
                        if (item.QUESTION_LEVEL == "1")
                        {
                            q.Question_Level = "Easy";
                        }
                        else if (item.QUESTION_LEVEL == "2")
                        {
                            q.Question_Level = "Medium";
                        }
                        else if (item.QUESTION_LEVEL == "3")
                        {
                            q.Question_Level = "Hard";
                        }

                        if (item.QUESTION_TYPE == "SINGLE_RESPONSE")
                        {
                            q.Question_Type = "Single response";
                        }
                        else if (item.QUESTION_TYPE == "MULTI_RESPONSE")
                        {
                            q.Question_Type = "Multi response";
                        }
                        else if (item.QUESTION_TYPE == "FILL_BLANK")
                        {
                            q.Question_Type = "Fill blank";
                        }
                        else if (item.QUESTION_TYPE == "ASSOCIATE")
                        {
                            q.Question_Type = "Associate";
                        }
                        else if (item.QUESTION_TYPE == "ORDER_ITEMS")
                        {
                            q.Question_Type = "Order items";
                        }
                        this.listQuestionSelected.Add(q);
                    }
                }
                else if (Section != null)
                {
                    txtDesc.Text = Section.Test_Section_Desc;

                    var list = BLL_Test_Section.GetQuestions(this._section_ID);

                    // Store list question
                    foreach (var item in Section.Questions)
                    {
                        //var q = new QuestionDisplay();

                        //q.User_ID = item.USER_ID;
                        //q.Question_ID = item.QUESTION_ID;
                        //q.Question_Desc = item.QUESTION_DESCRIPTION;
                        //if (item.QUESTION_LEVEL == "1")
                        //{
                        //    q.Question_Level = "Easy";
                        //}
                        //else if (item.QUESTION_LEVEL == "2")
                        //{
                        //    q.Question_Level = "Medium";
                        //}
                        //else if (item.QUESTION_LEVEL == "3")
                        //{
                        //    q.Question_Level = "Hard";
                        //}

                        //if (item.QUESTION_TYPE == "SINGLE_RESPONSE")
                        //{
                        //    q.Question_Type = "Single response";
                        //}
                        //else if (item.QUESTION_TYPE == "MULTI_RESPONSE")
                        //{
                        //    q.Question_Type = "Multi response";
                        //}
                        //else if (item.QUESTION_TYPE == "FILL_BLANK")
                        //{
                        //    q.Question_Type = "Fill blank";
                        //}
                        //else if (item.QUESTION_TYPE == "ASSOCIATE")
                        //{
                        //    q.Question_Type = "Associate";
                        //}
                        //else if (item.QUESTION_TYPE == "ORDER_ITEMS")
                        //{
                        //    q.Question_Type = "Order items";
                        //}
                        this.listQuestionSelected.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                // Show error message
            }
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            try
            {
                var filter = new QuestionFilter(null, null, null);
                if (this.cboLectureFilter.SelectedIndex >= 0)
                {
                    filter.User_ID = this.cboLectureFilter.SelectedValue.ToString();
                }
                if (this.cboDifficult.SelectedIndex >= 0)
                {
                    filter.Difficulty = this.cboDifficult.SelectedValue.ToString();
                }
                if (this.cboType.SelectedIndex >= 0)
                {
                    filter.Type = this.cboDifficult.SelectedValue.ToString();
                }

                var listQuestion = new BLL_Question().Load(new QUESTION
                {
                    USER_ID = filter.User_ID,
                    QUESTION_LEVEL = filter.Difficulty,
                    QUESTION_TYPE = filter.Type
                });

                // Store list question
                foreach (var item in listQuestion)
                {
                    this.listQuestion.Add(new QuestionDisplay
                                     {
                                         User_ID = item.USER_ID,
                                         Question_ID = item.QUESTION_ID,
                                         Question_Level = item.QUESTION_LEVEL,
                                         Question_Type = item.QUESTION_TYPE,
                                         Question_Desc = item.QUESTION_DESCRIPTION
                                     });
                }

                var listTemp = this.listQuestion.Except(this.listQuestionSelected, new QuestionDisplayComparer()).ToList();
                if (listTemp.Count() != this.listQuestion.Count)
                {
                    this.listQuestion.Clear();
                    foreach (var item in listTemp)
                    {
                        this.listQuestion.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                // Show message here
            }
        }

        private void btnSelect_Click(object sender, EventArgs e)
        {
            if (this.dgvQuestion.SelectedRows.Count > 0)
            {
                // Move to question selected list
                foreach (DataGridViewRow item in this.dgvQuestion.SelectedRows)
                {
                    this.listQuestionSelected.Add(new QuestionDisplay
                    {
                        Question_ID = Convert.ToInt32(item.Cells["Question_ID"].Value),
                        User_ID= item.Cells["User_ID"].Value.ToString(),
                        Question_Desc = item.Cells["Question_Desc"].Value == null ? null : item.Cells["Question_Desc"].Value.ToString(),
                        Question_Type = item.Cells["Question_Type"].Value.ToString(),
                        Question_Level = item.Cells["Question_Level"].Value.ToString()
                    });
                    this.listQuestion.Remove(item.DataBoundItem as QuestionDisplay);
                }

                this.dgvQuestion.ClearSelection();
                this.dgvQuestionSelected.ClearSelection();
            }
        }

        private void btnSelectAll_Click(object sender, EventArgs e)
        {
            foreach (var item in this.listQuestion)
            {
                this.listQuestionSelected.Add(item);
            }

            this.listQuestion.Clear();
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            if (this.dgvQuestionSelected.SelectedRows.Count > 0)
            {
                this.listQuestion.Add(this.dgvQuestionSelected.SelectedRows[0].DataBoundItem as QuestionDisplay);
                this.listQuestionSelected.Remove(this.dgvQuestionSelected.SelectedRows[0].DataBoundItem as QuestionDisplay);
            }

            this.dgvQuestion.ClearSelection();
            this.dgvQuestionSelected.ClearSelection();
        }

        private void btnClearAll_Click(object sender, EventArgs e)
        {
            foreach (var item in this.listQuestionSelected)
            {
                this.listQuestion.Add(item);
            }

            this.listQuestionSelected.Clear();

            this.dgvQuestion.ClearSelection();
            this.dgvQuestionSelected.ClearSelection();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (Section == null)
            {
                Section = new TestSection();
            }
            Section.Test_Section_ID = this._section_ID;
            Section.Test_Section_Desc = txtDesc.Text.Trim();
            Section.Questions = this.listQuestionSelected.ToList();
            Section.Num_Question = Section.Questions.Count;
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.Close();
        }

        #region Helper Methods

        private List<Course> GetCourses()
        {
            var listCourse = new List<Course>();

            try
            {
                var listDTOCourse = BLL_Course.LoadAll();
                foreach (var item in listDTOCourse)
                {
                    listCourse.Add(new Course(item.COURSE_ID, item.COURSE_NAME));
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return listCourse;
        }

        private List<User> GetUsers()
        {
            var listUser = new List<User>();

            try
            {
                var listDTOUser = BLL_User.LoadAll();
                foreach (var item in listDTOUser)
                {
                    listUser.Add(new User(item.USER_ID, item.USER_LAST_NAME + ", " + item.USER_FIRST_NAME));
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return listUser;
        }

        private List<Diffculty> GetDifficulty()
        {
            var listDifficulty = new List<Diffculty>();
            listDifficulty.Add(new Diffculty(1, "Easy"));
            listDifficulty.Add(new Diffculty(1, "Medium"));
            listDifficulty.Add(new Diffculty(1, "Hard"));

            return listDifficulty;
        }

        private List<QuestionType> GetQuestionTypes()
        {
            var listQuestionType = new List<QuestionType>();
            listQuestionType.Add(new QuestionType("SINGLE_RESPONSE", "Single response"));
            listQuestionType.Add(new QuestionType("MULTI_RESPONSE", "Multi Response"));
            listQuestionType.Add(new QuestionType("FILL_BLANK", "Fill blank"));
            listQuestionType.Add(new QuestionType("ASSOCIATE", "Associate"));
            listQuestionType.Add(new QuestionType("ORDER_ITEMS", "Order items"));
            return listQuestionType;
        }

        //private void FillTestControl()
        //{
        //    // Fill data into Test combobox
        //    try
        //    {
        //        if (this.cboCourse.SelectedIndex == -1 && this.cboLecture.SelectedIndex == -1)
        //        {
        //            this.cboTest.DataSource = new List<USER_TEST_COURSE>();
        //            return;
        //        }

        //        // Load data and show in datagrid view
        //        var filter = new TestingManager.Filter(null, null);
        //        if (this.cboCourse.SelectedIndex >= 0)
        //        {
        //            filter.Course_ID = this.cboCourse.SelectedValue.ToString();
        //        }
        //        if (this.cboLecture.SelectedIndex >= 0)
        //        {
        //            filter.User_ID = this.cboLecture.SelectedValue.ToString();
        //        }

        //        var list = BLL_Test.Load(new TEST
        //        {
        //            COURSE_ID = filter.Course_ID,
        //            USER_ID = filter.User_ID
        //        });

        //        this.cboTest.DataSource = (from x in list
        //                                   select new TestingManager.UserTestCourse
        //                                   {
        //                                       Test_ID = x.TEST_ID,
        //                                       Test_Desc = x.TEST_DESC
        //                                   }).ToList();
        //        this.cboTest.SelectedIndex = -1;
        //    }
        //    catch (Exception ex)
        //    {
        //        // Show error message
        //    }
        //}

        #endregion
    }

    class QuestionDisplayComparer : IEqualityComparer<QuestionDisplay>
    {
        public bool Equals(QuestionDisplay x, QuestionDisplay y)
        {

            //Check whether the compared objects reference the same data.
            if (Object.ReferenceEquals(x, y)) return true;

            //Check whether any of the compared objects is null.
            if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
                return false;

            //Check whether the question id propertie are equal.
            return x.Question_ID == y.Question_ID;
        }

        // If Equals() returns true for a pair of objects 
        // then GetHashCode() must return the same value for these objects.

        public int GetHashCode(QuestionDisplay questionDisplay)
        {
            //Check whether the object is null
            if (Object.ReferenceEquals(questionDisplay, null)) return 0;

            //Get hash code for the question id field.
            int hashProductCode = questionDisplay.Question_ID.GetHashCode();

            //Calculate the hash code for the question display.
            return hashProductCode;
        }
    }
}
